classdef jwlong_ZNB40_class
    % 修改时间： 20241114_07h23m12s
    %     instrreset
    % 1、执行连接函数
    % VNA=jwlong_ZNB40_class.Conect('keysight','TCPIP0::192.168.100.2::5025::SOCKET');
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    properties
        VNA
        idn
    end
    properties(Constant)
        e0 = 8.854187817e-12;
        u0 = 4*pi*1e-07;
        c0 = 2.99792458e+08;
    end
    methods
        function jwl = jwlong_ZNB40_class

        end  
    end
    
    methods (Static)%不需要创建对象，也可以直接调用的函数
        % 20240620_08h41m53s修改
        function jwl = Conect(company,visa_address)
%             instrreset
            jwl = jwlong_ZNB40_class;
            jwl.VNA = visa(company,visa_address);
            MAXPOINT = 3001;
            jwl.VNA.InputBufferSize = 20*MAXPOINT*2;%读取曲线时，单次传输最大字符数
            jwl.VNA.Timeout=60;
            fopen(jwl.VNA);
            jwl.idn=jwl.SendAndReadMessage('*IDN?');
            
%             jwl.SendMessage('DISP:WIND 0;');
%             jwl.SendMessage('DISP:WIND:STATE ON;');
%             jwl.SendMessage('CALC:PAR:DEF ''MyMeas'',S21;');%设置测试S11
%             jwl.SendMessage('DISP:WIND:TRAC1:FEED ''MyMeas'';');
%             jwl.SendMessage('SENS:SWE:TYPE LIN;');
%             jwl.SendMessage('INIT:CONT ON');%ON连续模式 OFF为触发模式
%             jwl.SendMessage('DISP:WIND:TRAC:Y:AUTO ONCE');%设置autoscale
        end  
    end
    
    methods % 创建对象后才可以调用的函数
        function SendMessage(jwl,command)
            % 发送命令
            fprintf(jwl.VNA,command);
        end
        
        function str=ReadMessage(jwl)
            % 读取字符串信息
            str=fscanf(jwl.VNA);
        end
        
        function str=SendAndReadMessage(jwl,query)
            % 发送并且读取字符串信息
            fprintf(jwl.VNA,query);
            str=fscanf(jwl.VNA);
        end
                             
        function SetAutoScale(obj)
            obj.SendMessage('DISP:WIND:TRAC:Y:AUTO ONCE');%设置autoscale
        end
        
        function SetPreSet(obj)
            obj.SendMessage('*RST');%设置preset
        end        
        
        
        function SetFreq(obj,setType,freq)
            %   要先初始化之后才能调用 
            %   VNA = jwlong_N5227B_class;
            %   [VNA.VNA,VNA.idn]=VNA.InitVNA('keysight','TCPIP0::192.168.100.2::5025::SOCKET');
            %   VNA.SetFreq(VNA,'start',1e9);
 
            if (strcmp(setType,'start'))||(strcmp(setType,'START'))
                message = ['SENS:FREQ:START ' num2str(freq)];   
            elseif (strcmp(setType,'stop'))||(strcmp(setType,'STOP'))
                message = ['SENS:FREQ:STOP ' num2str(freq)]; 
            elseif (strcmp(setType,'cent'))||(strcmp(setType,'CENT'))
                message = ['SENS:FREQ:CENT ' num2str(freq)]; 
            elseif (strcmp(setType,'span'))||(strcmp(setType,'SPAN'))
                message = ['SENS:FREQ:SPAN ' num2str(freq)];    
            end
            obj.SendMessage(message);
        end       
        
       function SetFreqPoint(obj,freqpoint)
             obj.SendMessage(['SENS:SWE:POIN ',num2str(freqpoint),';']);
       end
        
        function out = SetSweepTime(obj,sweeptime)
           if (sweeptime>0)
               %                obj.SendMessage('SENS:SWE:TIME:AUTO OFF');
               obj.SendMessage(['SENS:SWE:TIME ',num2str(sweeptime),';']);
           end
           out=str2double(obj.SendAndReadMessage('SENS:SWE:Time?;\n'));
        end
       
        function SetIF(obj,ifband)
             obj.SendMessage(['SENS:BWID ',num2str(ifband),';']);
        end
 
        function SetPower(obj,power)
             obj.SendMessage(['SOUR:POW ',num2str(power),';']);
        end
        
        
        function OpenAverage(obj,avgnum)
            obj.SendMessage('SENS:AVER ON;');
            obj.SendMessage(['SENS:AVER:COUN ',num2str(avgnum),';\n']);
            obj.SendMessage('SENS:AVER:CLE');
        end      
        
        function OpenSmooth(obj,smoothrate)
            obj.SendMessage('CALC:SMO ON');
%             obj.SendMessage(['CALC:SMO:POIN ',num2str(smoothrate)]);
            obj.SendMessage(['CALC:SMO:APER ',num2str(smoothrate)]);
        end
        
        function CloseSmooth(obj)
            obj.SendMessage('CALC:SMO OFF');
        end
        
        function SetMarker(obj,makertype,makernumber)
            %  makertype='OFF' 关闭 AOFF 全关闭
            %  makertype='MAX'/ 'MIN'  3672C没有PEAK
            % 
            if strcmp(makertype,'AOFF')
                obj.SendMessage('CALC:MARK:AOFF;');
            elseif strcmp(makertype,'OFF')
                obj.SendMessage(['CALC:MARK',num2str(makernumber),' OFF;']);
            else
                obj.SendMessage(['CALC:MARK',num2str(makernumber),' ON;']);
                obj.SendMessage(['CALC:MARK',num2str(makernumber),':FUNC:EXEC ',makertype]); 
                obj.SendMessage(['CALC:MARK',num2str(makernumber),':FUNC:TRAC ON']);
            end
        end
        
        function SetMarkerBW(obj,bw)
%             obj.SendMessage('CALC:MEAS:MARK:BWID ON');
%             obj.SendMessage(['CALC:MARK:BWID ',num2str(bw)]);%设置带宽
            
            % 20241114_06h43m07s调试
            obj.SendMessage(':CALC:MARK:SEAR:BFIL:RES ON;');   
            obj.SendMessage(['CALC:MARK:BWID ',num2str(abs(bw))]);%设置带宽
            obj.SendMessage(':CALC:MARK:FUNC:BWID:MODE BPAS;');
            obj.SendMessage(':CALC:MARK:FUNC:EXEC BFIL;');
            obj.SendMessage('CALC:MARK:SEAR:TRAC ON');
            
%             obj.SendMessage(':CALC:MARK:SEAR:BFIL:RES ON;');
%             obj.SendMessage(['CALC:MARK:BWID ',num2str(abs(bw))]);%设置带宽
        end
        
        
        
        function [markX,markY] = ReadMark(obj,number)
            clrdevice(obj.VNA);
            message = ['CALC:MARK',int2str(number),':X?'];
            obj.SendMessage(message);
            temp = fscanf(obj.VNA);
            markX = str2double(temp);
            clrdevice(obj.VNA);
            message = ['CALC:MARK',int2str(number),':Y?'];
            obj.SendMessage(message);
            temp = fscanf(obj.VNA);
            MarkY = str2num(temp);
            markY = MarkY(1);
        end
        
        function [fbw,f0,Q0,loss] = ReadQ(obj,bw)
            obj.SetMarkerBW(bw)
            clrdevice(obj.VNA)
            obj.SendMessage('CALC:MARK:BWID?');
            temp = fscanf(obj.VNA);
            BWdata = str2num(temp);%去掉前后的双引号
            fbw = BWdata(1);
            f0  = BWdata(2);
            Q0  = BWdata(3);
            loss= BWdata(4);
        end
        
        function [fbw,f0,Q0,loss] = FindQ(obj,freqcent,freqbw)
            Qbw = [-10,-5,-3.5,-3];
%             Qbw = [-0.3,-0.2,-0.1,-0.05]; %调试的时候用的
            tempfreq = freqcent;
            tempfbw = freqbw;
            for i=1:max(size(Qbw))
                obj.SetFreq('CENT',tempfreq);
                obj.SetFreq('SPAN',tempfbw);
                obj.SetMarkerBW(Qbw(i))
                obj.OpenAverage(30);                
                obj.OpenSmooth(0.2);
                pause(1);
                obj.SetAutoScale();               
                if i==max(size(Qbw))
                    obj.OpenSmooth(5);
                    pause(3);  % 最后一次多平均会儿
                else
                    pause(1); 
                end                
                [fbw,f0,Q0,loss] = obj.ReadQ(Qbw(i));
                fprintf(' Qbw= %.1f,fbw=%.4fMHz,f0=%.4fGHz,Q0=%.1f,loss=%.1f\n',Qbw(i),fbw/1e6,f0/1e9,Q0,loss)
                tempfreq = f0;
                if tempfbw~=0
                    tempfbw = fbw;
                end
            end           
            obj.OpenAverage(1);
            obj.CloseSmooth();
            obj.SetFreq('SPAN',freqbw);
            pause(0.5);
            obj.SetAutoScale();
        
        end
         
        
        function SetContinus(obj,on_off)
            obj.SendMessage('INIT:CONT ON');%  
            obj.SendMessage('INIT:CONT OFF');
            % 重复设置一下是因为：如果意外变成了off，直接设置on没法切换，必须先off再on才能实现
            obj.SendMessage(['INIT:CONT ',on_off]);%ON连续模式 OFF为触发模式            
        end
        
        function SendTrig(obj)
            obj.SendMessage('INIT:IMMediate');%ON连续模式 OFF为触发模式            
        end
        
        % 读取曲线的值
        % 20241114_06h54m48s修改
        function trace = ReadTrace(obj)
            obj.SetContinus('OFF');
            obj.SendTrig();
            pause(3);
            obj.SetAutoScale();
            obj.SendMessage('FORM:DATA ASC');
            obj.SendMessage('SENS:SWEep:POIN?');
            point = fscanf(obj.VNA,'%d');
            obj.SendMessage('SENS:FREQ:START?');
            f_start = fscanf(obj.VNA,'%f');
            obj.SendMessage('SENS:FREQ:STOP?');
            f_stop = fscanf(obj.VNA,'%f');
            freq = linspace(f_start,f_stop,point)';
            
            obj.SendMessage('CALC:DATA? SDATA;');
            pause(0.5);
            tracedata = fscanf(obj.VNA);
            data = str2num(tracedata);
            real = zeros(point,1);
            imag = zeros(point,1);
            mag = zeros(point,1);
            pha = zeros(point,1);
            for i=1:point
               real(i) = data(i*2-1);
               imag(i) = data(i*2);
               complexdata = real(i) + 1i* imag(i);
               mag(i) = 20*log10( sqrt( real(i)^2 + imag(i)^2 ) );
               pha(i) = angle(complexdata)*180/pi;
%                pha(i) = atan(imag(i)/real(i)) * 180/pi;
            end
            trace.freq = freq;
            trace.real = real;
            trace.imag = imag;
            trace.mag = mag;
            trace.pha = pha;
            trace.point = point;
            %             plot(freq/1e9,mag)
            obj.SendMessage('CALC:FORMat MLOG;\n');
            obj.SetContinus('ON');
        end
        
        % 20241114_06h54m48s修改
         function trace = ReadTraceF(obj)
            obj.SetContinus('OFF');
            obj.SendTrig();
            pause(3);
            obj.SetAutoScale();
            obj.SendMessage('FORM:DATA ASC');
            obj.SendMessage('SENS:SWEep:POIN?');
            point = fscanf(obj.VNA,'%d');
            obj.SendMessage('SENS:FREQ:START?');
            f_start = fscanf(obj.VNA,'%f');
            obj.SendMessage('SENS:FREQ:STOP?');
            f_stop = fscanf(obj.VNA,'%f');
            freq = linspace(f_start,f_stop,point)';
            
            obj.SendMessage('CALC:FORMat REAL;\n');
            tracedata1=obj.SendAndReadMessage('CALC:DATA? FDATA;');
            pause(0.5);
            obj.SendMessage('CALC:FORMat IMAG;\n');
            tracedata2=obj.SendAndReadMessage('CALC:DATA? FDATA;');
            pause(0.5);
%             tracedata = fscanf(obj.VNA);
            data1 = str2num(tracedata1);
            data2 = str2num(tracedata2);
            real = zeros(point,1);
            imag = zeros(point,1);
            mag = zeros(point,1);
            pha = zeros(point,1);
            for i=1:point
               real(i) = data1(i);
               imag(i) = data2(i);
               complexdata = real(i) + 1i* imag(i);
               mag(i) = 20*log10( sqrt( real(i)^2 + imag(i)^2 ) );
               pha(i) = angle(complexdata)*180/pi;
%                pha(i) = atan(imag(i)/real(i)) * 180/pi;
            end
            trace.freq = freq;
            trace.real = real;
            trace.imag = imag;
            trace.mag = mag;
            trace.pha = pha;
            trace.point = point;
            obj.SendMessage('CALC:FORMat MLOG;\n');
            obj.SetContinus('ON');
        end
        
        % 20241114_06h54m48s添加
        % 设置测量曲线
        function SetTrace(obj,type)            
            obj.SendMessage("DISP1:ANN:TRAC OFF;\n");
            obj.SendMessage(['CALC1:PAR:SDEF ''jwCh1Tr1'', ''' ,type,'''']);%设置测试s参数
            obj.SendMessage("DISP1:WIND1:STATE ON;\n");
            obj.SendMessage("DISP1:WIND1:TRAC1:DELete;\n");
            obj.SendMessage("DISP1:WIND1:TRAC1:FEED 'jwCh1Tr1';\n");
        end
        
    end
    
end